﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using Newtonsoft.Json;
using eCommerce.core;
using eCommerce.core.Helpers;
using eCommerce.db.BORespository;
using eCommerce.db.DataRespository;
using eCommerce.log;

namespace eCommerce.db.Action
{
    public class ProductAction : IBaseAction
    {
        public void Do(HttpContext context)
        {
            var actionName = Utils.GetIdFromRequestString(Utils.Action, string.Empty);

            var responseData = new ResponseData();
            switch (actionName)
            {
                case "search":
                    responseData = ListSearch();
                    break;
                case "getproductbycategory":
                    responseData = ListByCategory();
                    break;

                case "getproduct":
                    responseData = GetProduct();
                    break;

                case "changestatus":
                    responseData = ChangeStatus();
                    break;

                case "readexcel":
                    responseData = ReadExcel();
                    break;
                case "executeexcel":
                    responseData = ExecuteExcel();
                    break;
                case "save":
                    responseData = Save();
                    break;
                case "delete":
                    responseData = Delete();
                    break;

                case "":
                    responseData.Success = false;
                    responseData.Message = "Can not found this action.";
                    break;
            }

            var jSonString = JsonConvert.SerializeObject(responseData, Utils.SerializeFormat("MM/dd/yyyy HH:mm:ss"));
            if (!string.IsNullOrEmpty(context.Request.Params["callback"]))
                jSonString = string.Format("{0}({1})", context.Request.Params["callback"], jSonString);
            context.Response.Write(jSonString);
        }

        public static ResponseData ListByCategory()
        {
            var responseData = new ResponseData();            
            var categoryId  = Utils.GetIdFromRequestString(Utils.CategoryId, 0);            

            try
            {
                var lstProduct = ProductBo.GetListByCategoryId(categoryId);                

                responseData.Success  = true;
                responseData.Data     = lstProduct;
                responseData.TotalRow = lstProduct.Rows.Count;                
            }
            catch (Exception ex)
            {
                responseData.Success = false;
                responseData.Message = ex.Message;
                Logger.WriteLog(Logger.LogType.Error, ex.Message);
            }

            return responseData;
        }

        private static ResponseData ListSearch()
        {
            var responseData = new ResponseData();
            
            var keyword     = Utils.GetIdFromRequestString(Utils.Keyword, string.Empty);
            var categoryId  = Utils.GetIdFromRequestString(Utils.CategoryId, 0);
            var status      = Utils.GetIdFromRequestString(Utils.Status, 0);
            var orderBy     = Utils.GetIdFromRequestString(Utils.OrderBy, 0);
            var pageIndex   = Utils.GetIdFromRequestString(Utils.PageIndex, 0);
            var pageSize    = Utils.GetIdFromRequestString(Utils.PageSize, 0);

            try
            {
                var totalRecords = 0;
                var lstProduct = ProductBo.Search(keyword, categoryId, status, orderBy, pageIndex, pageSize, ref totalRecords);

                for (int i = 0; i < lstProduct.Count; i++)
                {
                    lstProduct[i].ItemIndex          = Utils.CalcItemIndex(i, pageIndex, pageSize);
                    lstProduct[i].FormatUnitPrice    = Utils.FormatPrice(lstProduct[i].UnitPrice);
                    lstProduct[i].FormatSpecialPrice = Utils.FormatPrice(lstProduct[i].SpecialPrice);                    
                    switch (lstProduct[i].Status)
                    {
                        case (int)ProductStatus.Temp:
                            lstProduct[i].IconStatus = "<a class='btn14 topDir' title='Tạm dừng'><img src='/images/icons/dark/denied.png' alt=''/></a>";
                            break;
                        case (int)ProductStatus.Published:
                            lstProduct[i].IconStatus = "<a class='btn14 topDir' title='Kích hoạt'><img src='/images/icons/dark/check.png' alt=''/></a>";
                            break;                        
                    }
                }

                responseData.Success  = true;
                responseData.Data     = lstProduct;
                responseData.TotalRow = totalRecords;
                responseData.Pager    = PagerHelper.PageLinks(pageIndex, pageSize, totalRecords, Constant.PageStep, UrlHelper.PagerProduct);
            }
            catch (Exception ex)
            {
                responseData.Success = false;
                responseData.Message = ex.Message;
                Logger.WriteLog(Logger.LogType.Error, ex.Message);
            }

            return responseData;
        }

        private static ResponseData GetProduct()
        {
            var responseData = new ResponseData();
            var id = Utils.GetIdFromRequestString(Utils.ProductId, 0);

            try
            {
                var product = ProductBo.GetById(id);

                responseData.Success = true;
                responseData.Data = product;
                responseData.TotalRow = 1;
            }
            catch (Exception ex)
            {
                responseData.Success = false;
                responseData.Message = ex.Message;
                Logger.WriteLog(Logger.LogType.Error, ex.Message);
            }
            return responseData;
        }

        private static ResponseData ChangeStatus()
        {
            var responseData = new ResponseData();

            var id      = Utils.GetIdFromRequestString(Utils.ProductId, 0);            
            var status  = Utils.GetIdFromRequestString(Utils.Status, 0);            
            try
            {                
                ProductBo.UpdateStatus(id, status);

                responseData.Success = true;
                responseData.Data = null;
                responseData.TotalRow = 0;
            }
            catch (Exception ex)
            {
                responseData.Success = false;
                responseData.Message = ex.Message;
                Logger.WriteLog(Logger.LogType.Error, ex.Message);
            }
            return responseData;
        }

        public static ResponseData ReadExcel()
        {
            var responseData = new ResponseData();
            var categoryId  = Utils.GetIdFromRequestString(Utils.CategoryId, 0);
            var typeId      = Utils.GetIdFromRequestString(Utils.TypeId, 0);
            var status      = Utils.GetIdFromRequestString(Utils.Status, 0);
            var filePath    = Utils.GetIdFromRequestString(Utils.FilePath, string.Empty);

            if (filePath.Length > 0)
            {
                using (SpreadsheetDocument document = SpreadsheetDocument.Open(HttpContext.Current.Server.MapPath(filePath), true))
                {
                    var errorMessage = string.Empty;

                    try
                    {
                        Workbook workBook               = document.WorkbookPart.Workbook;
                        IEnumerable<Sheet> workSheets   = workBook.Descendants<Sheet>();
                        SharedStringTable sharedStrings = document.WorkbookPart.SharedStringTablePart.SharedStringTable;

                        string sheetName = workSheets.First(s => s.Name == @"Product").Id;

                        WorksheetPart productSheet = (WorksheetPart)document.WorkbookPart.GetPartById(sheetName);

                        
                        List<ProductEntity> lstProduct = ProductBo.GetDataExcel(categoryId, status, typeId, productSheet.Worksheet, sharedStrings, ref errorMessage);

                        if (errorMessage == string.Empty && lstProduct.Count > 0)
                        {
                            responseData.Success = true;
                            responseData.Data = lstProduct;
                        }
                        else
                        {
                            responseData.Success = false;
                            responseData.Message = errorMessage;
                        }
                    }
                    catch (Exception ex)
                    {
                        responseData.Success = false;
                        responseData.Message = errorMessage;
                        Logger.WriteLog(Logger.LogType.Error, ex.Message);
                    }
                }    
            }    
        
            return responseData;
        }

        public static ResponseData ExecuteExcel()
        {
            var responseData = new ResponseData();
            var categoryId  = Utils.GetIdFromRequestString(Utils.CategoryId, 0);
            var typeId      = Utils.GetIdFromRequestString(Utils.TypeId, 0);
            var status      = Utils.GetIdFromRequestString(Utils.Status, 0);
            var filePath    = Utils.GetIdFromRequestString(Utils.FilePath, string.Empty);

            if (filePath.Length > 0)
            {
                using (SpreadsheetDocument document = SpreadsheetDocument.Open(HttpContext.Current.Server.MapPath(filePath), true))
                {
                    var errorMessage = string.Empty;

                    try
                    {
                        Workbook workBook = document.WorkbookPart.Workbook;
                        IEnumerable<Sheet> workSheets = workBook.Descendants<Sheet>();
                        SharedStringTable sharedStrings = document.WorkbookPart.SharedStringTablePart.SharedStringTable;

                        string sheetName = workSheets.First(s => s.Name == @"Product").Id;

                        WorksheetPart productSheet = (WorksheetPart)document.WorkbookPart.GetPartById(sheetName);

                        List<ProductEntity> lstProduct = ProductBo.GetDataExcel(categoryId, status, typeId, productSheet.Worksheet, sharedStrings, ref errorMessage);

                        var count = 0;
                        foreach (var item in lstProduct)
                        {
                            count++;
                            var o = new ProductEntity();
                            o.CategoryId    = item.CategoryId;
                            o.Status        = item.Status;
                            o.Code          = item.Code;
                            o.Name          = item.Name;
                            o.Url           = string.Empty;
                            o.Description   = item.Description.Equals("0") ? string.Empty : item.Description;                            
                            o.ImagePath     = string.Format("/Data/UserData/1/{0}/{1}/{2}a.jpg", Utils.UnsignAndDash(item.ParentName), Utils.UnsignAndDash(item.Name), item.Code);
                            o.Content       = string.Empty;
                            o.UnitPrice     = item.UnitPrice * 1000;
                            o.SpecialPrice  = item.SpecialPrice * 1000;
                            o.CreatedBy     = HttpContext.Current.User.Identity.Name.Replace(Utils.GetSetting("SitePrefix", SettingType.String).ToString(), string.Empty);

                            var iProduct = ProductBo.Create(o);

                            if (iProduct > 0)
                            {
                                // Images
                                if (item.ImageCount > 0)
                                {
                                    for (int i = 0; i < item.ImageCount; i++)
                                    {
                                        #region Alpha
                                        var alpha = string.Empty;
                                        switch (i)
                                        {
                                            case 0:
                                                alpha = "a";
                                                break;
                                            case 1:
                                                alpha = "b";
                                                break;
                                            case 2:
                                                alpha = "c";
                                                break;
                                            case 3:
                                                alpha = "d";
                                                break;
                                            case 4:
                                                alpha = "e";
                                                break;
                                            case 5:
                                                alpha = "f";
                                                break;
                                        }
                                        #endregion

                                        var imgItem = new ImageEntity();
                                        imgItem.ProductId   = iProduct;
                                        imgItem.Priority    = i + 1;
                                        imgItem.ImagePath   = string.Format("/Data/UserData/1/{0}/{1}/{2}{3}.jpg", Utils.UnsignAndDash(item.ParentName), Utils.UnsignAndDash(item.Name), item.Code, alpha);
                                        imgItem.Description = string.Empty;

                                        ImageBo.Create(imgItem);
                                    }
                                }

                                // Property Value
                                foreach (var ppvItem in item.LstPropertyValue)
                                {
                                    var ppv = new ProductPropertyValueEntity();
                                    ppv.ProductId       = iProduct;
                                    ppv.PropertyValueId = ppvItem.PropertyValueId;                                    
                                    ppv.Description     = ppvItem.Name;

                                    ProductPropertyValueBo.Create(ppv);
                                }   
                            }
                        }

                        responseData.Success = true;
                        responseData.Data    = count;
                        responseData.Message = string.Format("{0} bản ghi đã được lưu vào db thành công!", count);                        
                    }
                    catch (Exception ex)
                    {
                        responseData.Success = false;
                        responseData.Message = errorMessage;
                        Logger.WriteLog(Logger.LogType.Error, ex.Message);
                    }
                }
            }

            return responseData;
        }        

        private static ResponseData Save()
        {
            var responseData = new ResponseData();

            var id = Utils.GetIdFromRequestString(Utils.ProductId, 0);
            var categoryId   = Utils.GetIdFromRequestString(Utils.CategoryId, 0);
            var status       = Utils.GetIdFromRequestString(Utils.Status, 0);
            var code         = Utils.GetIdFromRequestString(Utils.Mobile, string.Empty);
            var name         = Utils.GetIdFromRequestString(Utils.Email, string.Empty);            
            var desc         = Utils.GetIdFromRequestString(Utils.Description, string.Empty);
            var imgPath      = Utils.GetIdFromRequestString(Utils.ImagePath, string.Empty);
            var content      = Utils.GetIdFromRequestString(Utils.Content, string.Empty);
            var unitPrice    = Utils.GetIdFromRequestString(Utils.UnitPrice, 0);
            var specialPrice = Utils.GetIdFromRequestString(Utils.SpecialPrice, 0);
            var username = Utils.GetIdFromRequestString(Utils.UserName, "Unknow");

            try
            {
                ProductEntity o = null;
                if (id > 0)
                {
                    o = ProductBo.GetById(id);
                    o.ProductId     = id;
                    o.CategoryId    = categoryId;
                    o.Status        = status;
                    o.Code          = code;
                    o.Name          = name;
                    o.Description   = desc;
                    o.ImagePath     = imgPath;
                    o.Content       = content;
                    o.UnitPrice     = unitPrice;
                    o.SpecialPrice  = specialPrice;
                    o.EditedBy      = username;
                }
                else
                {
                    o = new ProductEntity();
                    o.CategoryId    = categoryId;
                    o.Status        = status;
                    o.Code          = code;
                    o.Name          = name;
                    o.Description   = desc;
                    o.ImagePath     = imgPath;
                    o.Content       = content;
                    o.UnitPrice     = unitPrice;
                    o.SpecialPrice  = specialPrice;
                    o.CreatedBy     = username;
                }

                ProductBo.Save(o);

                responseData.Success = true;
                responseData.Data = null;
                responseData.TotalRow = 0;
            }
            catch (Exception ex)
            {
                responseData.Success = false;
                responseData.Message = ex.Message;
                Logger.WriteLog(Logger.LogType.Error, ex.Message);
            }
            return responseData;
        }

        private static ResponseData Delete()
        {
            var responseData = new ResponseData();

            var id = Utils.GetIdFromRequestString(Utils.ProductId, 0);

            try
            {
                ProductBo.Delete(id);

                responseData.Success = true;
                responseData.Data = null;
                responseData.TotalRow = 0;
            }
            catch (Exception ex)
            {
                responseData.Success = false;
                responseData.Message = ex.Message;
                Logger.WriteLog(Logger.LogType.Error, ex.Message);
            }
            return responseData;
        }
    }
}

